#include "cwtrainer.h"
#include <random>
#include <chrono>
#include <thread>
#include <iomanip>
#include <sstream>

CWTrainer::CWTrainer() : 
    app(nullptr),
    window(nullptr),
    paned(nullptr),
    leftPanel(nullptr),
    rightPanel(nullptr),
    startButton(nullptr),
    inputEntry(nullptr),
    resultTextView(nullptr),
    resultBuffer(nullptr),
    isExerciseRunning(false) {
}

CWTrainer::~CWTrainer() {
    if (app) {
        g_object_unref(app);
    }
}

void CWTrainer::initialize() {
    // 初始化音频系统
    audioPlayer.initialize();
}

int CWTrainer::run(int argc, char** argv) {
    // 创建GTK应用
    app = gtk_application_new("com.cwtrainerX.app", G_APPLICATION_DEFAULT_FLAGS);
    
    // 连接 activate 信号到 createWindow 函数
    g_signal_connect(app, "activate", G_CALLBACK(createWindow), this);
    
    // 运行应用
    int status = g_application_run(G_APPLICATION(app), argc, argv);
    
    return status;
}

void CWTrainer::createLeftPanel() {
    // 创建左侧面板
    leftPanel = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
    // 设置左侧面板
    gtk_paned_set_start_child(GTK_PANED(paned), leftPanel);
    gtk_paned_set_resize_start_child(GTK_PANED(paned), TRUE);
    gtk_paned_set_shrink_start_child(GTK_PANED(paned), FALSE);
    
    // 创建开始按钮
    startButton = gtk_button_new_with_label("开始");
    
    // 设置按钮样式为圆形绿色
    GtkCssProvider *provider = gtk_css_provider_new();
    gtk_css_provider_load_from_data(provider, 
                                   "button {\n" 
                                   "  background-color: #4CAF50;\n" 
                                   "  color: black;\n" 
                                   "  border-radius: 50%;\n" 
                                   "  min-width: 100px;\n" 
                                   "  min-height: 100px;\n" 
                                   "  font-size: 16px;\n" 
                                   "  font-weight: bold;\n"
                                   "  border: none;\n"
                                   "  box-shadow: 0 4px 8px rgba(0,0,0,0.2);\n"
                                   "}\n"
                                   "button:hover {\n"
                                   "  background-color: #45a049;\n"
                                   "  box-shadow: 0 6px 12px rgba(0,0,0,0.3);\n"
                                   "}\n"
                                   "button:active {\n"
                                   "  background-color: #3d8b40;\n"
                                   "  transform: translateY(2px);\n"
                                   "  box-shadow: 0 2px 4px rgba(0,0,0,0.2);\n"
                                   "}", 
                                   -1);
    
    gtk_style_context_add_provider(gtk_widget_get_style_context(startButton),
                                  GTK_STYLE_PROVIDER(provider),
                                  GTK_STYLE_PROVIDER_PRIORITY_USER);
    g_object_unref(provider);
    
    // 连接信号
    g_signal_connect(startButton, "clicked", G_CALLBACK(onStartButtonClicked), this);
    
    // 创建垂直布局，使按钮和输入框可以定位
    GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
    gtk_box_set_homogeneous(GTK_BOX(vbox), FALSE);
    // 将 gtk_container_add 替换为 gtk_box_append
    gtk_box_append(GTK_BOX(leftPanel), vbox);
    
    // 添加顶部占位符
    GtkWidget *topSpacer = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    gtk_widget_set_size_request(topSpacer, -1, 180); // 30% of 600
    // 将 gtk_box_pack_start 替换为 gtk_box_append
    gtk_box_append(GTK_BOX(vbox), topSpacer);
    
    // 创建一个居中对齐的容器来放置圆形按钮
    GtkWidget *buttonAlign = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    gtk_widget_set_halign(buttonAlign, GTK_ALIGN_CENTER);
    gtk_widget_set_valign(buttonAlign, GTK_ALIGN_CENTER);
    gtk_box_append(GTK_BOX(vbox), buttonAlign);
    
    // 添加按钮到居中容器
    gtk_box_append(GTK_BOX(buttonAlign), startButton);
    
    // 添加中间占位符
    GtkWidget *middleSpacer = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    gtk_widget_set_size_request(middleSpacer, -1, 60); // 10% of 600
    gtk_box_append(GTK_BOX(vbox), middleSpacer);
    
    // 创建水平布局来放置输入框
    GtkWidget *hEntryBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    gtk_box_set_homogeneous(GTK_BOX(hEntryBox), TRUE);
    gtk_box_append(GTK_BOX(vbox), hEntryBox);
    
    // 创建输入框，宽度比左侧栏小2%
    inputEntry = gtk_entry_new();
    gtk_widget_set_size_request(inputEntry, 250, 30); // 800*40%*98% ≈ 313
    gtk_editable_set_editable(GTK_EDITABLE(inputEntry), FALSE);
    
    // 连接信号
    g_signal_connect(inputEntry, "changed", G_CALLBACK(onInputChanged), this);
    gtk_box_append(GTK_BOX(hEntryBox), inputEntry);
    
    // 添加底部占位符
    GtkWidget *bottomSpacer = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    gtk_box_append(GTK_BOX(vbox), bottomSpacer);
}

void CWTrainer::createRightPanel() {
    // 创建右侧面板
    rightPanel = gtk_scrolled_window_new();
    // 将 gtk_paned_pack2 替换为 gtk_paned_set_end_child
    gtk_paned_set_end_child(GTK_PANED(paned), rightPanel);
    gtk_paned_set_resize_end_child(GTK_PANED(paned), TRUE);
    gtk_paned_set_shrink_end_child(GTK_PANED(paned), FALSE);
    
    // 创建文本视图
    resultTextView = gtk_text_view_new();
    gtk_text_view_set_editable(GTK_TEXT_VIEW(resultTextView), FALSE);
    gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(resultTextView), GTK_WRAP_WORD_CHAR);
    // 设置为不换行以确保字符对齐
    // gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(resultTextView), GTK_WRAP_NONE);
    
    // 使用GTK4推荐的方式设置等宽字体
    GtkCssProvider *provider = gtk_css_provider_new();
    gtk_css_provider_load_from_data(provider, 
        "textview { "
        "  font-family: Monospace; "
        "  font-size: 12pt; "
        "}", -1);
    gtk_style_context_add_provider(gtk_widget_get_style_context(resultTextView),
                                   GTK_STYLE_PROVIDER(provider),
                                   GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
    g_object_unref(provider);
    
    // 获取文本缓冲区
    resultBuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(resultTextView));
    
    // 添加到滚动窗口
    // 将 gtk_container_add 替换为 gtk_scrolled_window_set_child
    gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(rightPanel), resultTextView);
}

// 还需要修改 createWindow 函数中的容器添加操作
void CWTrainer::createWindow(GtkApplication *app, gpointer data) {
    CWTrainer *trainer = static_cast<CWTrainer*>(data);
    
    // 创建主窗口
    trainer->window = gtk_application_window_new(app);
    gtk_window_set_title(GTK_WINDOW(trainer->window), "CW Trainer X");
    gtk_window_set_default_size(GTK_WINDOW(trainer->window), 800, 600);
    
    gtk_window_maximize(GTK_WINDOW(trainer->window));
    
    // 创建标题栏 (HeaderBar)
    GtkWidget *headerBar = gtk_header_bar_new();
    gtk_window_set_titlebar(GTK_WINDOW(trainer->window), headerBar);
    
    // 创建菜单
    trainer->createMenu();
    
    // 创建菜单按钮并添加到标题栏的右侧
    GtkWidget *menuButton = gtk_menu_button_new();
    gtk_menu_button_set_icon_name(GTK_MENU_BUTTON(menuButton), "open-menu-symbolic");
    gtk_menu_button_set_menu_model(GTK_MENU_BUTTON(menuButton), 
                                  G_MENU_MODEL(gtk_application_get_menubar(GTK_APPLICATION(app))));
    
    // 将菜单按钮添加到标题栏的右侧
    gtk_header_bar_pack_end(GTK_HEADER_BAR(headerBar), menuButton);
    
    // 创建分隔面板
    trainer->paned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
    // 将 gtk_container_add 替换为 gtk_window_set_child
    gtk_window_set_child(GTK_WINDOW(trainer->window), trainer->paned);
    
    // 创建左右面板
    trainer->createLeftPanel();
    trainer->createRightPanel();
    
    // 设置面板初始比例
    gtk_paned_set_position(GTK_PANED(trainer->paned), 320); // 40% of 800
    
    // 显示窗口
    gtk_window_present(GTK_WINDOW(trainer->window));
}

void CWTrainer::createMenu() {
    // 创建动作
    GSimpleAction *configAction = g_simple_action_new("config", nullptr);
    g_signal_connect(configAction, "activate", G_CALLBACK(onConfigMenuClicked), this);
    
    // 添加动作到应用
    g_action_map_add_action(G_ACTION_MAP(app), G_ACTION(configAction));
    
    // 创建菜单
    GMenu *menu = g_menu_new();
    g_menu_append(menu, "配置", "app.config");
    
    // 在GTK4中，我们需要将菜单设置为应用程序的菜单栏，这样菜单按钮才能正确引用它
    gtk_application_set_menubar(GTK_APPLICATION(app), G_MENU_MODEL(menu));
    
    g_object_unref(configAction);
    g_object_unref(menu);
}

void CWTrainer::onStartButtonClicked(GtkWidget *widget, gpointer data) {
    // 添加 [[maybe_unused]] 属性以避免未使用参数警告
    (void)widget;
    
    CWTrainer *trainer = static_cast<CWTrainer*>(data);
    
    if (!trainer->isExerciseRunning) {
        trainer->startCountdown();
    }
}

void CWTrainer::onConfigMenuClicked(GSimpleAction *action, GVariant *parameter, gpointer data) {
    // 添加 [[maybe_unused]] 属性以避免未使用参数警告
    (void)action;
    (void)parameter;
    
    CWTrainer *trainer = static_cast<CWTrainer*>(data);
    trainer->showConfigDialog();
}

void CWTrainer::onInputChanged(GtkEditable *editable, gpointer data) {
    CWTrainer *trainer = static_cast<CWTrainer*>(data);
    
    // 获取当前光标位置
    int cursorPos = gtk_editable_get_position(editable);

    // if (trainer->isExerciseRunning) {
        // 在GTK4中使用gtk_editable_get_text替代gtk_entry_get_text
    const gchar *inputText = gtk_editable_get_text(GTK_EDITABLE(editable));
    std::string inputStr(inputText);
        
    // 将输入转换为大写
    std::string upperStr = inputStr;
    std::transform(upperStr.begin(), upperStr.end(), upperStr.begin(), ::toupper);
    
    // 如果转换后与原字符串不同，则更新输入框内容
    if (inputStr != upperStr) {
        // 阻止递归调用
        g_signal_handlers_block_by_func(editable, (gpointer)onInputChanged, data);
        
        // 更新输入框内容为大写
        gtk_editable_set_text(GTK_EDITABLE(editable), upperStr.c_str());
        
        // 恢复光标位置
        gtk_editable_set_position(GTK_EDITABLE(editable), cursorPos);
        
        // 恢复信号处理
        g_signal_handlers_unblock_by_func(editable, (gpointer)onInputChanged, data);
    }
    if(trainer->isExerciseRunning)
        return;
    // 检查输入长度是否达到要求
    if (inputStr.length() >= trainer->currentCWString.length()) {
        trainer->checkInput();
        //新线程调用trainer->callPlayCW();
        std::thread playThread([trainer]() { trainer->callPlayCW(); });
        playThread.detach();
    }
    // }
}

// 在 showConfigDialog 函数中也需要更新容器操作
// ... existing code ...
void CWTrainer::showConfigDialog() {
    // 使用GtkWindow替代GtkDialog，这是GTK4推荐的方式
    GtkWidget *window = gtk_window_new();
    gtk_window_set_title(GTK_WINDOW(window), "配置");
    gtk_window_set_modal(GTK_WINDOW(window), TRUE);
    gtk_window_set_transient_for(GTK_WINDOW(window), GTK_WINDOW(this->window));
    
    // 创建主垂直容器
    GtkWidget *mainBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
    gtk_widget_set_margin_start(mainBox, 10);
    gtk_widget_set_margin_end(mainBox, 10);
    gtk_widget_set_margin_top(mainBox, 10);
    gtk_widget_set_margin_bottom(mainBox, 10);
    gtk_window_set_child(GTK_WINDOW(window), mainBox);
    
    // 创建内容网格
    GtkWidget *grid = gtk_grid_new();
    gtk_grid_set_column_spacing(GTK_GRID(grid), 10);
    gtk_grid_set_row_spacing(GTK_GRID(grid), 10);
    gtk_box_append(GTK_BOX(mainBox), grid);
    
    // 字符范围选择
    GtkWidget *charsetLabel = gtk_label_new("字符范围：");
    gtk_grid_attach(GTK_GRID(grid), charsetLabel, 0, 0, 1, 1);
    
    GtkWidget *lettersCheck = gtk_check_button_new_with_label("A-Z");
    gtk_check_button_set_active(GTK_CHECK_BUTTON(lettersCheck), config.getIncludeLetters());
    gtk_grid_attach(GTK_GRID(grid), lettersCheck, 0, 1, 1, 1);
    
    GtkWidget *numbersCheck = gtk_check_button_new_with_label("0-9");
    gtk_check_button_set_active(GTK_CHECK_BUTTON(numbersCheck), config.getIncludeNumbers());
    gtk_grid_attach(GTK_GRID(grid), numbersCheck, 1, 1, 1, 1);
    
    GtkWidget *questionCheck = gtk_check_button_new_with_label("?");
    gtk_check_button_set_active(GTK_CHECK_BUTTON(questionCheck), config.getIncludeQuestion());
    gtk_grid_attach(GTK_GRID(grid), questionCheck, 0, 2, 1, 1);
    
    GtkWidget *equalCheck = gtk_check_button_new_with_label("=");
    gtk_check_button_set_active(GTK_CHECK_BUTTON(equalCheck), config.getIncludeEqual());
    gtk_grid_attach(GTK_GRID(grid), equalCheck, 1, 2, 1, 1);
    
    GtkWidget *commaCheck = gtk_check_button_new_with_label(",");
    gtk_check_button_set_active(GTK_CHECK_BUTTON(commaCheck), config.getIncludeComma());
    gtk_grid_attach(GTK_GRID(grid), commaCheck, 0, 3, 1, 1);
    
    GtkWidget *periodCheck = gtk_check_button_new_with_label(".");
    gtk_check_button_set_active(GTK_CHECK_BUTTON(periodCheck), config.getIncludePeriod());
    gtk_grid_attach(GTK_GRID(grid), periodCheck, 1, 3, 1, 1);
    
    GtkWidget *slashCheck = gtk_check_button_new_with_label("/");
    gtk_check_button_set_active(GTK_CHECK_BUTTON(slashCheck), config.getIncludeSlash());
    gtk_grid_attach(GTK_GRID(grid), slashCheck, 0, 4, 1, 1);
    
    // 字符数量
    GtkWidget *charCountLabel = gtk_label_new("字符数量：");
    gtk_grid_attach(GTK_GRID(grid), charCountLabel, 0, 5, 1, 1);
    
    GtkWidget *charCountSpin = gtk_spin_button_new_with_range(1, 20, 1);
    gtk_spin_button_set_value(GTK_SPIN_BUTTON(charCountSpin), config.getCharCount());
    gtk_grid_attach(GTK_GRID(grid), charCountSpin, 1, 5, 1, 1);
    
    // WPM
    GtkWidget *wpmLabel = gtk_label_new("WPM：");
    gtk_grid_attach(GTK_GRID(grid), wpmLabel, 0, 6, 1, 1);
    
    GtkWidget *wpmSpin = gtk_spin_button_new_with_range(5, 40, 1);
    gtk_spin_button_set_value(GTK_SPIN_BUTTON(wpmSpin), config.getWpm());
    gtk_grid_attach(GTK_GRID(grid), wpmSpin, 1, 6, 1, 1);
    
    // 频率
    GtkWidget *freqLabel = gtk_label_new("频率(Hz)：");
    gtk_grid_attach(GTK_GRID(grid), freqLabel, 0, 7, 1, 1);
    
    GtkWidget *freqSpin = gtk_spin_button_new_with_range(450, 900, 1);
    gtk_spin_button_set_value(GTK_SPIN_BUTTON(freqSpin), config.getFrequency());
    gtk_grid_attach(GTK_GRID(grid), freqSpin, 1, 7, 1, 1);
    
    // 创建按钮区域
    GtkWidget *buttonBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
    gtk_widget_set_halign(buttonBox, GTK_ALIGN_END);
    gtk_box_append(GTK_BOX(mainBox), buttonBox);
    
    // 创建按钮
    GtkWidget *cancelButton = gtk_button_new_with_label("取消");
    GtkWidget *okButton = gtk_button_new_with_label("确定");
    
    // 为确定按钮添加CSS类以突出显示
    gtk_widget_add_css_class(okButton, "suggested-action");
    
    gtk_box_append(GTK_BOX(buttonBox), cancelButton);
    gtk_box_append(GTK_BOX(buttonBox), okButton);
    
    // 连接按钮信号
    g_signal_connect(cancelButton, "clicked", G_CALLBACK(+[](GtkButton *button, gpointer user_data) {
        GtkWidget *window = GTK_WIDGET(user_data);
        gtk_window_destroy(GTK_WINDOW(window));
    }), window);
    
    g_signal_connect(okButton, "clicked", G_CALLBACK(+[](GtkButton *button, gpointer user_data) {
        // 保存配置
        GtkWidget *window = GTK_WIDGET(user_data);
        GtkWidget *lettersCheck = GTK_WIDGET(g_object_get_data(G_OBJECT(window), "lettersCheck"));
        GtkWidget *numbersCheck = GTK_WIDGET(g_object_get_data(G_OBJECT(window), "numbersCheck"));
        GtkWidget *questionCheck = GTK_WIDGET(g_object_get_data(G_OBJECT(window), "questionCheck"));
        GtkWidget *equalCheck = GTK_WIDGET(g_object_get_data(G_OBJECT(window), "equalCheck"));
        GtkWidget *commaCheck = GTK_WIDGET(g_object_get_data(G_OBJECT(window), "commaCheck"));
        GtkWidget *periodCheck = GTK_WIDGET(g_object_get_data(G_OBJECT(window), "periodCheck"));
        GtkWidget *slashCheck = GTK_WIDGET(g_object_get_data(G_OBJECT(window), "slashCheck"));
        GtkWidget *charCountSpin = GTK_WIDGET(g_object_get_data(G_OBJECT(window), "charCountSpin"));
        GtkWidget *wpmSpin = GTK_WIDGET(g_object_get_data(G_OBJECT(window), "wpmSpin"));
        GtkWidget *freqSpin = GTK_WIDGET(g_object_get_data(G_OBJECT(window), "freqSpin"));
        
        Config *config = static_cast<Config*>(g_object_get_data(G_OBJECT(window), "config"));
        config->setIncludeLetters(gtk_check_button_get_active(GTK_CHECK_BUTTON(lettersCheck)));
        config->setIncludeNumbers(gtk_check_button_get_active(GTK_CHECK_BUTTON(numbersCheck)));
        config->setIncludeQuestion(gtk_check_button_get_active(GTK_CHECK_BUTTON(questionCheck)));
        config->setIncludeEqual(gtk_check_button_get_active(GTK_CHECK_BUTTON(equalCheck)));
        config->setIncludeComma(gtk_check_button_get_active(GTK_CHECK_BUTTON(commaCheck)));
        config->setIncludePeriod(gtk_check_button_get_active(GTK_CHECK_BUTTON(periodCheck)));
        config->setIncludeSlash(gtk_check_button_get_active(GTK_CHECK_BUTTON(slashCheck)));
        
        config->setCharCount(static_cast<int>(gtk_spin_button_get_value(GTK_SPIN_BUTTON(charCountSpin))));
        config->setWpm(static_cast<int>(gtk_spin_button_get_value(GTK_SPIN_BUTTON(wpmSpin))));
        config->setFrequency(static_cast<int>(gtk_spin_button_get_value(GTK_SPIN_BUTTON(freqSpin))));
        
        config->saveConfig();
        
        gtk_window_destroy(GTK_WINDOW(window));
    }), window);
    
    // 存储控件引用和配置对象以便在回调中使用
    g_object_set_data(G_OBJECT(window), "lettersCheck", lettersCheck);
    g_object_set_data(G_OBJECT(window), "numbersCheck", numbersCheck);
    g_object_set_data(G_OBJECT(window), "questionCheck", questionCheck);
    g_object_set_data(G_OBJECT(window), "equalCheck", equalCheck);
    g_object_set_data(G_OBJECT(window), "commaCheck", commaCheck);
    g_object_set_data(G_OBJECT(window), "periodCheck", periodCheck);
    g_object_set_data(G_OBJECT(window), "slashCheck", slashCheck);
    g_object_set_data(G_OBJECT(window), "charCountSpin", charCountSpin);
    g_object_set_data(G_OBJECT(window), "wpmSpin", wpmSpin);
    g_object_set_data(G_OBJECT(window), "freqSpin", freqSpin);
    g_object_set_data(G_OBJECT(window), "config", &config);
    
    // 显示窗口
    gtk_window_present(GTK_WINDOW(window));
}
// ... existing code ...
void CWTrainer::startCountdown() {
    if(isExerciseRunning)
        return;
    // 在GTK4中使用gtk_editable_set_text替代gtk_entry_set_text
    gtk_editable_set_text(GTK_EDITABLE(inputEntry), "");
    gtk_editable_set_editable(GTK_EDITABLE(inputEntry), TRUE);
    
    // 禁用开始按钮
    // gtk_widget_set_sensitive(startButton, FALSE);
    
    // 使用静态变量来跟踪计时器
    static int iTimers = 0;
    iTimers = 0; // 重置计时器
    // 生成一个定时器，每秒执行一次playBeepAndShowText函数
    // 使用静态函数而不是lambda表达式，将this作为user_data传递
    g_timeout_add_seconds(1, [](gpointer user_data) -> gboolean {
        // 重新声明静态变量以访问它
        iTimers++;
        if(iTimers > 3){
            // 获取CWTrainer实例并调用callPlayCW
            CWTrainer *trainer = static_cast<CWTrainer*>(user_data);
            trainer->appendToResultView("开始！\n");
            trainer->callPlayCW();
            return G_SOURCE_REMOVE;
        }
        // 获取CWTrainer实例并调用playBeepAndShowText
        CWTrainer *trainer = static_cast<CWTrainer*>(user_data);
        trainer->playBeepAndShowText(iTimers);
        return G_SOURCE_CONTINUE;
    }, this); // 将this作为user_data传递
}
void CWTrainer::callPlayCW() {
    
    // 设置输入焦点
    gtk_widget_grab_focus(inputEntry);
    // 生成并播放CW字符串
    generateCWString();
    //启动一个线程来运行playCWString()

    // 创建新线程来播放CW字符串，避免阻塞UI
    std::thread playThread([this]() {
        this->playCWString();
    });
    
    // 分离线程，让它独立运行
    playThread.detach();
}
void CWTrainer::playBeepAndShowText(int timers) {
    std::string countdownText = "准备开始... " + std::to_string(timers);
    appendToResultView(countdownText + "\n");
    //启动新线程播放提示音
    audioPlayer.playBeep();
}

void CWTrainer::generateCWString() {
    std::string charset = config.getCharset();
    if (charset.empty()) {
        // 如果没有选择字符范围，默认使用A-Z
        for (char c = 'A'; c <= 'Z'; ++c) {
            charset += c;
        }
    }
    
    currentCWString = generateRandomString(config.getCharCount(), charset);
}

void CWTrainer::playCWString() {
    std::string morseCode = morseConverter.stringToMorse(currentCWString);
    isExerciseRunning = true;
    audioPlayer.playMorseCode(morseCode, config.getFrequency(), config.getBaseTime());
    isExerciseRunning = false;
    // gtk_widget_set_sensitive(startButton, TRUE);
}

void CWTrainer::checkInput() {
    // 在GTK4中使用gtk_editable_get_text替代gtk_entry_get_text
    const gchar *inputText = gtk_editable_get_text(GTK_EDITABLE(inputEntry));
    //如果inputText长度大于config.numCharCount，只取前config.numCharCount个字符
    if(strlen(inputText) > (size_t)config.getCharCount()){
        inputText = strndup(inputText, (size_t)config.getCharCount());
    }
    std::string userAnswer(inputText);
    //userAnswer转为大写
    std::transform(userAnswer.begin(), userAnswer.end(), userAnswer.begin(), ::toupper);

    appendToResultView(currentCWString + "\t->\t");
    displayResult(userAnswer);
    
    // 在GTK4中使用gtk_editable_set_text替代gtk_entry_set_text
    gtk_editable_set_text(GTK_EDITABLE(inputEntry), "");
    gtk_editable_set_editable(GTK_EDITABLE(inputEntry), TRUE);
    // 重新启用开始按钮
    // gtk_widget_set_sensitive(startButton, TRUE);
}

void CWTrainer::displayResult(const std::string& inputStr) {
    // 计算正确的字符数量
    int minLength = std::min(currentCWString.length(), inputStr.length());
    
    for (int i = 0; i < minLength; ++i) {
        if (toupper(currentCWString[i]) == toupper(inputStr[i])) {
            correctCount++;
        }
    }
    
    // 计算正确率
    float accuracy = 0.0f;
    runCount += currentCWString.length();
    if (runCount > 0) {
        accuracy = static_cast<float>(correctCount) /runCount * 100.0f;
    }
    
    // 构建结果字符串
    std::stringstream ss;
    // ss << currentCWString << "->";
    
    // 显示输入字符串，错误字符为红色
    for (size_t i = 0; i < inputStr.length(); ++i) {
        if (i < currentCWString.length() && toupper(inputStr[i]) != toupper(currentCWString[i])) {
            appendToResultView(std::string(1, inputStr[i]), "red");
        } else {
            appendToResultView(std::string(1, inputStr[i]));
        }
    }
    
    // 显示统计信息
    ss << "\t" << correctCount << "/" << runCount << "  正确率 " << std::fixed << std::setprecision(2) << accuracy << "%";
    appendToResultView(ss.str() + "\n");
}

std::string CWTrainer::generateRandomString(int length, const std::string& charset) {
    std::string result;
    
    // 检查字符集是否为空
    if (charset.empty()) {
        return result;
    }
    
    // 使用随机设备生成随机数
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<> distrib(0, charset.size() - 1);
    
    // 生成随机字符串
    for (int i = 0; i < length; ++i) {
        result += charset[distrib(gen)];
    }
    
    return result;
}

void CWTrainer::appendToResultView(const std::string& text, const std::string& color) {
    // 获取缓冲区末尾位置
    GtkTextIter endIter;
    gtk_text_buffer_get_end_iter(resultBuffer, &endIter);
    
    // 创建标签（如果需要）
    if (color != "black") {
        std::string tagName = "color_" + color;
        
        // 检查标签是否已存在
        GtkTextTagTable *tagTable = gtk_text_buffer_get_tag_table(resultBuffer);
        if (!gtk_text_tag_table_lookup(tagTable, tagName.c_str())) {
            // 创建新标签
            GtkTextTag *tag = gtk_text_tag_new(tagName.c_str());
            g_object_set(tag, "foreground", color.c_str(), nullptr);
            gtk_text_tag_table_add(tagTable, tag);
            g_object_unref(tag);
        }
        
        // 插入带标签的文本
        gtk_text_buffer_insert_with_tags_by_name(resultBuffer, &endIter, text.c_str(), -1, tagName.c_str(), nullptr);
    } else {
        // 插入普通文本
        gtk_text_buffer_insert(resultBuffer, &endIter, text.c_str(), -1);
    }
    
    // 滚动到底部
    gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(resultTextView),
                                      gtk_text_buffer_get_insert(resultBuffer));
}